//-------------------------------------------------------------------------------------------------------
//      Copyright (c) 2005-2009, Be Nanashi-San 
// 
//      Permission is hereby granted, free of charge, to any person obtaining a 
//      copy of this software and associated documentation files (the "Software"), 
//      to deal in the Software without restriction, including without limitation 
//      the rights to use, copy, modify, merge, publish, distribute, sublicense, 
//      and/or sell copies of the Software, and to permit persons to whom the 
//      Software is furnished to do so, subject to the following conditions: 
// 
//      The above copyright notice and this permission notice shall be included in 
//      all copies or substantial portions of the Software. 
// 
//      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
//      IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
//      FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
//      AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
//      LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
//      FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
//      DEALINGS IN THE SOFTWARE. 
// 
//      File Name:   	MUtils.cpp
//      Author:      	Be Nanashi-San@598 in "BeOS - Zeta R4" Thread 
//						(http://pc8.2ch.net/test/read.cgi/os/1120676818/598)
//		Description:	MActionList
//-------------------------------------------------------------------------------------------------------
#include <Debug.h>
#include <stdio.h>
#include "MUtils.h"
//	TODO:ファイル名の変更（MStyleを分離後、ActionList.{cpp,h}？）

//2006.3.25 list > vector
//2006.3 clone() sakujyo
/////////////////////////////////////////////////////////////////////////////////
// MakeEmpty
//
//
////////////////////////////////////////////////////////////////////////////////
MActionList::MActionList(BTextView *target)
:fTarget(target)
, fAction(NULL)
{
	fActionArray.reserve(2048);
}

MActionList::~MActionList()
{
	for(std::vector<action_info*>::iterator i = fActionArray.begin(); i != fActionArray.end(); i++){
		delete *i;
	}
}
/////////////////////////////////////////////////////////////////////////////////
// Clear
//
//
////////////////////////////////////////////////////////////////////////////////
void
MActionList::Clear()
{
	for(std::vector<action_info*>::iterator i = fActionArray.begin(); i != fActionArray.end(); i++){
		delete *i;
	}
	
	fActionArray.clear();
	fActionArray.reserve(2048);
	fAction = NULL;
}
////////////////////////////////////////////////////////////////////////////////
// AddItem
//
//
////////////////////////////////////////////////////////////////////////////////
void
MActionList::AddAction(action_info *action)
{
	fActionArray.push_back(action);
}
////////////////////////////////////////////////////////////////////////////////
// ItemTo
// ItemTo:offsetの範囲に含まれるactionを返す
//	MouseMovedで頻繁に呼び出されるのでfStart、fFinishで限定されるのは効果が期待される
//	ただ適切に更新されないと『あるのに見つからない』ということになりかねない 
////////////////////////////////////////////////////////////////////////////////
action_info*
MActionList::ItemTo(int32 offset)
{
	if (fActionArray.empty()) return NULL;

	if (fAction && fAction->offset <= offset && offset <= fAction->offset + fAction->length)
		return fAction;

	//二分探索のような物
	uint32 start = 0, end = fActionArray.size();
	if(end > 20){
		uint32 j = (start + end) / 2;
		fAction = fActionArray[j];
		if(offset >(fAction->offset + fAction->length) ){ 
			start = j;
		}else if(fAction->offset > offset){
			end = j;
		} 
		j = (start + end) / 2;
		fAction = fActionArray[j];
		if(offset >(fAction->offset + fAction->length) ){ 
			start = j;
		}else if(fAction->offset > offset){
			end = j;
		} 
	}

	for (uint32 i = start; i < end; i++) {
		fAction = fActionArray[i];
		if (fAction->offset <= offset && offset <= fAction->offset + fAction->length)
			return fAction;
	}
	return NULL;
}
